import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { ElementPropertyConfig, PropertyChangeObject } from '@farris/ide-property-panel';
import { EventEditorService, DomService, WebCmdService, FormBasicService } from '@farris/designer-services';
import { TemplateButton } from '../template-binding-editor.component';
import { EventsEditorFuncUtils } from '../../../../../../../utils/events-editor-func';
import { FormPropertyChangeObject } from '../../../../../../../entity/property-change-entity';
import { MessagerService } from '@farris/ui-messager';

@Component({
  selector: 'template-button-editor',
  templateUrl: './template-button-editor.component.html',
  styleUrls: ['./template-button-editor.component.css']
})
export class TemplateButtonEditorComponent implements OnInit, OnChanges {

  @Input() viewModelId: string;

  @Input() buttons: TemplateButton[];

  /** 触发模板编辑器的保存方法 */
  @Input() triggerModalSave: any;

  @Output() buttonAdded = new EventEmitter<string>();

  @Output() buttonRemoved = new EventEmitter<TemplateButton>();

  @Output() moveUpButton = new EventEmitter<TemplateButton>();

  @Output() moveDownButton = new EventEmitter<TemplateButton>();

  selectedButton: any;

  propertyConfig;

  propertyData;


  constructor(
    private domService: DomService,
    private webCmdService: WebCmdService,
    private formBasicService: FormBasicService,
    private eventEditorService: EventEditorService,
    private msgService: MessagerService) { }

  ngOnInit() {
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.buttons) {
      this.updateButtons();
    }
  }

  private updateButtons() {
    if (this.buttons && this.buttons.length) {
      if (this.buttons.indexOf(this.selectedButton) < 0) {
        this.selectedButton = this.buttons[0];
      }
    } else {
      this.selectedButton = {};
    }
    this.updatePropertyPanel();
  }

  /**
   * 更新属性面板
   */
  private updatePropertyPanel() {
    // 属性面板
    this.propertyData = this.selectedButton;
    this.propertyConfig = this.getPropertyConfig();
  }

  selectButtonChanged(button: TemplateButton) {
    this.selectedButton = button;
    this.updatePropertyPanel();
  }

  private getPropertyConfig(): ElementPropertyConfig[] {
    const eventConfig = this.getEventPropertyConfig(this.propertyData, this.viewModelId);
    return [
      {
        categoryId: 'usual',
        categoryName: '常规',
        properties: [
          {
            propertyID: 'id',
            propertyName: '标识',
            propertyType: 'string',
            readonly: true
          },
          {
            propertyID: 'text',
            propertyName: '文本',
            propertyType: 'string',
            readonly: false
          },
          {
            propertyID: 'appearance',
            propertyName: '样式',
            propertyType: 'cascade',
            cascadeConfig: [
              {
                propertyID: 'class',
                propertyName: '按钮样式',
                propertyType: 'string'
              }
            ]
          }]
      },
      eventConfig
    ];
  }
  // 事件编辑器集成
  private getEventPropertyConfig(propertyData: any, viewModelId: string): ElementPropertyConfig {
    const self = this;
    const domService = this.domService;
    const webCmdService = this.webCmdService;
    const formBasicService = this.formBasicService;
    const eventEditorService = this.eventEditorService;
    const eventList = [
      {
        label: 'click',
        name: '点击事件'
      }
    ];
    return {
      categoryId: 'eventsEditor',
      categoryName: '事件',
      properties: EventsEditorFuncUtils.formProperties(eventEditorService, formBasicService, domService, webCmdService, propertyData, viewModelId, eventList),
      tabId: 'commands',
      tabName: '交互',
      hideTitle: true,
      setPropertyRelates(changeObject: FormPropertyChangeObject, data, parameters) {
        delete propertyData[viewModelId];

        // 若需要跳转到代码视图，首先要求用户将当前弹出窗口关闭
        if (parameters.isAddControllerMethod) {
          self.msgService.question('确定关闭当前编辑器并跳转到代码视图吗？', () => {
            const result = self.triggerModalSave();
            if (result) {
              EventsEditorFuncUtils.saveRelatedParameters(eventEditorService, domService, webCmdService, propertyData, viewModelId, eventList, parameters);
              this.properties = EventsEditorFuncUtils.formProperties(eventEditorService, formBasicService, domService, webCmdService, propertyData, viewModelId, eventList);
            }

          });
        } else {
          EventsEditorFuncUtils.saveRelatedParameters(eventEditorService, domService, webCmdService, propertyData, viewModelId, eventList, parameters);
          this.properties = EventsEditorFuncUtils.formProperties(eventEditorService, formBasicService, domService, webCmdService, propertyData, viewModelId, eventList);
        }
      }
    };
  }
  /**
   * 新增节点
   * @param isRoot 是否一级节点
   */
  addItem() {
    this.buttonAdded.emit();
  }

  /**
   * 删除节点
   */
  removeItem(button: TemplateButton) {
    this.buttonRemoved.emit(button);
  }

  /**
   * 上移
   */
  moveUpItem(button: TemplateButton) {
    this.moveUpButton.emit(button);
  }

  /**
   * 下移
   */
  moveDownItem(button: TemplateButton) {
    this.moveDownButton.emit(button);
  }

  trackById(index: number, button: TemplateButton): string { return button.id; }

  propertyChanged(changeObject: PropertyChangeObject) {
    if (changeObject.propertyID === 'text') {
      this.updateControlMap();
    }
  }
  onPropertyModalChanged(e) {
    this.addControlMapForEventPath(e);
  }

  private addControlMapForEventPath(e) {
    const changeObject: PropertyChangeObject = e.changeObject;
    const param = e.parameters;

    // 交互面板有变更时，触发更新事件路径
    if (changeObject.categoryId !== 'eventsEditor' || !param || !param.events || !param.events.length) {
      return;
    }
    // 若没有父级控件id，则不设置事件路径
    this.updateControlMap();
  }

  /**
   * 更新按钮的路径信息，用于交互面板显示
   */
  private updateControlMap() {

    const nodeText = this.propertyData.text;
    this.domService.controlBasicInfoMap.set(this.propertyData.id, {
      showName: nodeText,
      parentPathName: `列表 > ${nodeText}`
    });
  }

}
